#include "options_sequential.h"

/** Nacte nastaveni z daneho XML elementu.
 * \param settings XML element s nastaveni sekvencniho algoritmu
 */
void SequentialOptions::Read(ticpp::Element * settings) {
	settings->GetAttributeOrDefault("all", &all, false);
	std::string s;
	// initial ordering
	s = settings->GetAttributeOrDefault("ordering", "GeneralizedLargestFirstExclude");
	if (!STRCMP(s.c_str(), "LargestFirst")) ordering = LargestFirst;
	else if (!STRCMP(s.c_str(), "LargestFirstExclude")) ordering = LargestFirstExclude;
	else if (!STRCMP(s.c_str(), "SmallestLast")) ordering = SmallestLast;
	else if (!STRCMP(s.c_str(), "GeneralizedLargestFirst")) ordering = GLargestFirst;
	else if (!STRCMP(s.c_str(), "GeneralizedLargestFirstExclude")) ordering = GLargestFirstExclude;
	else if (!STRCMP(s.c_str(), "GeneralizedSmallestLast")) ordering = GSmallestLast;
	else if (!STRCMP(s.c_str(), "Random")) ordering = Random;
	else {
		ordering = GLargestFirstExclude;
		Log() << "Neplatna volba ordering: " << s << ". Pouzivam GeneralizedLargestFirstExclude." << std::endl;
	}
	// next transmitter selection
	s = settings->GetAttributeOrDefault("next", "Sequential");
	if (!STRCMP(s.c_str(), "Sequential")) next = Sequential;
	else if (!STRCMP(s.c_str(), "GSD")) next = GSD;
	else {
		next = Sequential;
		Log() << "Neplatna volba next: " << s << ". Pouzivam Sequential." << std::endl;
	}
	// frequency selection algorithm
	s = settings->GetAttributeOrDefault("frequency", "Smallest");
	if (!STRCMP(s.c_str(), "Smallest")) frequency = Smallest;
	else if (!STRCMP(s.c_str(), "Occupied")) frequency = Occupied;
	else if (!STRCMP(s.c_str(), "SmallestOccupied")) frequency = SmallestOccupied;
	else if (!STRCMP(s.c_str(), "HeaviestOccupied")) frequency = HeaviestOccupied;
	else {
		frequency = Smallest;
		Log() << "Neplatna volba frequency: " << s << ". Pouzivam Smallest." << std::endl;
	}
}

/** Vypise do logu informace o nastaveni algoritmu.
 */
void SequentialOptions::Print() {
	Log() << GetTitle() << " = nastaveni sekvencniho algoritmu: ";
	if (!all) {
		Log() << " setrideni = " << SequentialOrderingNames[ordering] << ", dalsi antena = " << (next == Sequential ? "Sequential" : "GSD")
			<< ", vyber frekvence = " << SequentialFrequencyNames[frequency];
	}
	else {
		Log() << "vsechny varianty";
	}
	Log() << std::endl;
}

/** Vrati kratky popis nastaveni algoritmu.
 * \return popis nastaveni sekvencniho algoritmu 
 */
std::string SequentialOptions::GetTitle() {
	std::string separator = "-";
	return SequentialOrderingShort[ordering] + separator + (next == Sequential ? "Seq" : "GSD") + separator + SequentialFrequencyShort[frequency];
}

/** Nacte dalsi kombinaci nastaveni sekvencniho algoritmu.
 * \return true, pokud se povedlo nacist dalsi nastaveni
 */
bool SequentialOptions::Next() {
	/* create next configuration */
	if (all) {
		all = false;
		return true;
	}
	else if (frequency < HeaviestOccupied) {
		frequency = (SequentialFrequency)(frequency + 1);
	}
	else if (next < GSD) {
		next = (SequentialNext)(next + 1);
		frequency = Smallest;
	}
	else if (ordering < Random) {
		ordering = (SequentialOrdering)(ordering + 1);
		frequency = Smallest;
		next = Sequential;
	}
	else {
		return false;
	}
	return true;
}
